#ifndef __BEV_FUSION_H__
#define __BEV_FUSION_H__
#include <Eigen/Core>
#include <array>

#include "common/data_scene.h"
#include "common/data_type.h"
#include "common/infer_common.h"
#include "preprocess/image_preprocessor.h"
#include "preprocess/voxel_preprocessor.h"
#include "amba_net.h"
#include "bev_net.h"
#include "grid_sample.h"
#include "image_encoder.h"

class BevFusion {
private:
  // 264 * 59 * 2:--- 264 * 128
  static constexpr std::uint32_t kCat2491{264 * 128};
  // 264 * 80 * 2 -----264 * 256
  static constexpr std::uint32_t kCat2492{264 * 256};

  static constexpr std::uint32_t kGridSampleResSize{256 * 128 * 128 * 2};
 public:
  // struct ImageOutbuffer {
  //   std::shared_ptr<std::array<char, kCat2491>> cat2491;
  //   std::shared_ptr<std::array<char, kCat2492>> cat2492;
  // };

  struct ImageOutbuffer {
    char* cat2491;
    char* cat2492;
  };

  struct Config {
    std::string image_encoder_path;
    std::string grid_sample_path;
    std::string bev_net_path;
    std::string input_dir;

    std::string input_image_path;
    std::string pre_input_path;
    std::string align_matrix_path;
    std::string ring_matrix_path;
    std::string ray_matrix_path;
    std::string lidar_input_path;
    std::string kCat2491_path;
    std::string kCat2492_path;
    std::string k2647_path;

    std::uint8_t type_size;
    OutLocation out_location;
    // std::unordered_map<std::string, std::uint8_t> out_index;
  };  


  struct FusionBevSettings {
    uint32_t cameras;
    /// @brief trt infer settings
    // TrtInferSettings infer_settings;
    /// @brief image pre process settings
    ImagePreProcessParameters image_pre_process_parameters;
    /// @brief voxel pre processor parameters
    VoxelProcessor::VoxelPreProcessParameters voxel_pre_process_parameters;
    /// @brief  obj decode parameter
    // LatticeNetDecode::ObjDecodeParameter obj_decode_parameter;
    // /// @brief lanemaker decode parameter
    // LatticeNetDecode::MapDecodeParameter map_decode_parameter;
  };


  BevFusion() noexcept;
  ~BevFusion() noexcept;

  BevFusion(BevFusion const &) = delete;
  BevFusion(BevFusion const &&) = delete;
  BevFusion &operator=(BevFusion const &) = delete;
  BevFusion &operator=(BevFusion const &&) = delete;

  uint32_t Init(Config const& config) noexcept;
  uint32_t Run(DataBuf& data_frame) noexcept;

  uint32_t Test(Config const& config) noexcept;
  static void GridSampleCallback(void *vpHandle, uint32_t flexidag_output_num,
                          flexidag_memblk_t *pblk_Output, void *vpParameter);
  static void ImageEncoderCallback(void *vpHandle, uint32_t flexidag_output_num,
                            flexidag_memblk_t *pblk_Output, void *vpParameter);

  static constexpr std::uint8_t kImageNum{6};  

  ImageEncoder image_encoder;
  GridSample grid_sample;
  BevNet bev_net;

  char* grid_buffer_;
  // std::unique_ptr<std::array<char, kGridSampleResSize>> grid_buffer_;
  ImageOutbuffer image_out_buf_;


  /// @brief decoder
  LatticeNetDecode decoder_;
  /// @brief infer output data raw
  InferOutputDataRaw output_data_raw_;

  std::array<std::array<LocationItem, InferBoxType::COUNT>, 8> box_infer_;   
  std::array<std::array<LocationItem, 2>, 3> map_infer_;

};

#endif